home *** CD-ROM | disk | FTP | other *** search
- ; INT9.ASM
- ;
- ; A short TSR to provide a driver for the keyboard hardware interrupt.
- ;
- ; Note that this code does not patch into int 2Fh (multiplex interrupt)
- ; nor can you remove this code from memory except by rebooting.
- ; If you want to be able to do these two things (as well as check for
- ; a previous installation), see the chapter on resident programs. Such
- ; code was omitted from this program because of length constraints.
- ;
- ;
- ; cseg and EndResident must occur before the standard library segments!
-
- cseg segment para public 'code'
- OldInt9 dword ?
- cseg ends
-
- ; Marker segment, to find the end of the resident section.
-
- EndResident segment para public 'Resident'
- EndResident ends
-
- .xlist
- include stdlib.a
- includelib stdlib.lib
- .list
-
-
- NumLockScan equ 45h
- ScrlLockScan equ 46h
- CapsLockScan equ 3ah
- CtrlScan equ 1dh
- AltScan equ 38h
- RShiftScan equ 36h
- LShiftScan equ 2ah
- InsScanCode equ 52h
- DelScanCode equ 53h
-
- ; Bits for the various modifier keys
-
- RShfBit equ 1
- LShfBit equ 2
- CtrlBit equ 4
- AltBit equ 8
- SLBit equ 10h
- NLBit equ 20h
- CLBit equ 40h
- InsBit equ 80h
-
-
- KbdFlags equ <byte ptr ds:[17h]>
- KbdFlags2 equ <byte ptr ds:[18h]>
- KbdFlags3 equ <byte ptr ds:[96h]>
- KbdFlags4 equ <byte ptr ds:[97h]>
-
- byp equ <byte ptr>
-
-
- cseg segment para public 'code'
- assume ds:nothing
-
- ; Scan code translation table.
- ; The incoming scan code from the keyboard selects a row.
- ; The modifier status selects the column.
- ; The word at the intersection of the two is the scan/ASCII code to
- ; put into the PC's type ahead buffer.
- ; If the value fetched from the table is zero, then we do not put the
- ; character into the type ahead buffer.
- ;
- ; norm shft ctrl alt num caps shcap shnum
-
- ScanXlat word 0000h, 0000h, 0000h, 0000h, 0000h, 0000h, 0000h, 0000h
- word 011bh, 011bh, 011bh, 011bh, 011bh, 011bh, 011bh, 011bh ;ESC
- word 0231h, 0231h, 0000h, 7800h, 0231h, 0231h, 0231h, 0321h ;1 !
- word 0332h, 0340h, 0300h, 7900h, 0332h, 0332h, 0332h, 0332h ;2 @
- word 0433h, 0423h, 0000h, 7a00h, 0433h, 0433h, 0423h, 0423h ;3 #
- word 0534h, 0524h, 0000h, 7b00h, 0534h, 0534h, 0524h, 0524h ;4 $
- word 0635h, 0625h, 0000h, 7c00h, 0635h, 0635h, 0625h, 0625h ;5 %
- word 0736h, 075eh, 071eh, 7d00h, 0736h, 0736h, 075eh, 075eh ;6 ^
-
- word 0837h, 0826h, 0000h, 7e00h, 0837h, 0837h, 0826h, 0826h ;7 &
- word 0938h, 092ah, 0000h, 7f00h, 0938h, 0938h, 092ah, 092ah ;8 *
- word 0a39h, 0a28h, 0000h, 8000h, 0a39h, 0a39h, 0a28h, 0a28h ;9 (
- word 0b30h, 0b29h, 0000h, 8100h, 0b30h, 0b30h, 0b29h, 0b29h ;0 )
- word 0c2dh, 0c5fh, 0000h, 8200h, 0c2dh, 0c2dh, 0c5fh, 0c5fh ;- _
- word 0d3dh, 0d2bh, 0000h, 8300h, 0d3dh, 0d3dh, 0d2bh, 0d2bh ;= +
- word 0e08h, 0e08h, 0e7fh, 0000h, 0e08h, 0e08h, 0e08h, 0e08h ;bksp
- word 0f09h, 0f00h, 0000h, 0000h, 0f09h, 0f09h, 0f00h, 0f00h ;Tab
-
- ; norm shft ctrl alt num caps shcap shnum
- word 1071h, 1051h, 1011h, 1000h, 1071h, 1051h, 1051h, 1071h ;Q
- word 1177h, 1057h, 1017h, 1100h, 1077h, 1057h, 1057h, 1077h ;W
- word 1265h, 1245h, 1205h, 1200h, 1265h, 1245h, 1245h, 1265h ;E
- word 1372h, 1352h, 1312h, 1300h, 1272h, 1252h, 1252h, 1272h ;R
- word 1474h, 1454h, 1414h, 1400h, 1474h, 1454h, 1454h, 1474h ;T
- word 1579h, 1559h, 1519h, 1500h, 1579h, 1559h, 1579h, 1559h ;Y
- word 1675h, 1655h, 1615h, 1600h, 1675h, 1655h, 1675h, 1655h ;U
- word 1769h, 1749h, 1709h, 1700h, 1769h, 1749h, 1769h, 1749h ;I
-
- word 186fh, 184fh, 180fh, 1800h, 186fh, 184fh, 186fh, 184fh ;O
- word 1970h, 1950h, 1910h, 1900h, 1970h, 1950h, 1970h, 1950h ;P
- word 1a5bh, 1a7bh, 1a1bh, 0000h, 1a5bh, 1a5bh, 1a7bh, 1a7bh ;[ {
- word 1b5dh, 1b7dh, 1b1dh, 0000h, 1b5dh, 1b5dh, 1b7dh, 1b7dh ;] }
- word 1c0dh, 1c0dh, 1c0ah, 0000h, 1c0dh, 1c0dh, 1c0ah, 1c0ah ;enter
- word 1d00h, 1d00h, 1d00h, 1d00h, 1d00h, 1d00h, 1d00h, 1d00h ;ctrl
- word 1e61h, 1e41h, 1e01h, 1e00h, 1e61h, 1e41h, 1e61h, 1e41h ;A
- word 1f73h, 1f5eh, 1f13h, 1f00h, 1f73h, 1f53h, 1f73h, 1f53h ;S
-
- ; norm shft ctrl alt num caps shcap shnum
- word 2064h, 2044h, 2004h, 2000h, 2064h, 2044h, 2064h, 2044h ;D
- word 2166h, 2146h, 2106h, 2100h, 2166h, 2146h, 2166h, 2146h ;F
- word 2267h, 2247h, 2207h, 2200h, 2267h, 2247h, 2267h, 2247h ;G
- word 2368h, 2348h, 2308h, 2300h, 2368h, 2348h, 2368h, 2348h ;H
- word 246ah, 244ah, 240ah, 2400h, 246ah, 244ah, 246ah, 244ah ;J
- word 256bh, 254bh, 250bh, 2500h, 256bh, 254bh, 256bh, 254bh ;K
- word 266ch, 264ch, 260ch, 2600h, 266ch, 264ch, 266ch, 264ch ;L
- word 273bh, 273ah, 0000h, 0000h, 273bh, 273bh, 273ah, 273ah ;; :
-
- word 2827h, 2822h, 0000h, 0000h, 2827h, 2827h, 2822h, 2822h ;' "
- word 2960h, 297eh, 0000h, 0000h, 2960h, 2960h, 297eh, 297eh ;` ~
- word 2a00h, 2a00h, 2a00h, 2a00h, 2a00h, 2a00h, 2a00h, 2a00h ;LShf
- word 2b5ch, 2b7ch, 2b1ch, 0000h, 2b5ch, 2b5ch, 2b7ch, 2b7ch ;\ |
- word 2c7ah, 2c5ah, 2c1ah, 2c00h, 2c7ah, 2c5ah, 2c7ah, 2c5ah ;Z
- word 2d78h, 2d58h, 2d18h, 2d00h, 2d78h, 2d58h, 2d78h, 2d58h ;X
- word 2e63h, 2e43h, 2e03h, 2e00h, 2e63h, 2e43h, 2e63h, 2e43h ;C
- word 2f76h, 2f56h, 2f16h, 2f00h, 2f76h, 2f56h, 2f76h, 2f56h ;V
-
- ; norm shft ctrl alt num caps shcap shnum
- word 3062h, 3042h, 3002h, 3000h, 3062h, 3042h, 3062h, 3042h ;B
- word 316eh, 314eh, 310eh, 3100h, 316eh, 314eh, 316eh, 314eh ;N
- word 326dh, 324dh, 320dh, 3200h, 326dh, 324dh, 326dh, 324dh ;M
- word 332ch, 333ch, 0000h, 0000h, 332ch, 332ch, 333ch, 333ch ;, <
- word 342eh, 343eh, 0000h, 0000h, 342eh, 342eh, 343eh, 343eh ;. >
- word 352fh, 353fh, 0000h, 0000h, 352fh, 352fh, 353fh, 353fh ;/ ?
- word 3600h, 3600h, 3600h, 3600h, 3600h, 3600h, 3600h, 3600h ;rshf
- word 372ah, 0000h, 3710h, 0000h, 372ah, 372ah, 0000h, 0000h ;* PS
-
- word 3800h, 3800h, 3800h, 3800h, 3800h, 3800h, 3800h, 3800h ;alt
- word 3920h, 3920h, 3920h, 0000h, 3920h, 3920h, 3920h, 3920h ;spc
- word 3a00h, 3a00h, 3a00h, 3a00h, 3a00h, 3a00h, 3a00h, 3a00h ;caps
- word 3b00h, 5400h, 5e00h, 6800h, 3b00h, 3b00h, 5400h, 5400h ;F1
- word 3c00h, 5500h, 5f00h, 6900h, 3c00h, 3c00h, 5500h, 5500h ;F2
- word 3d00h, 5600h, 6000h, 6a00h, 3d00h, 3d00h, 5600h, 5600h ;F3
- word 3e00h, 5700h, 6100h, 6b00h, 3e00h, 3e00h, 5700h, 5700h ;F4
- word 3f00h, 5800h, 6200h, 6c00h, 3f00h, 3f00h, 5800h, 5800h ;F5
-
- ; norm shft ctrl alt num caps shcap shnum
- word 4000h, 5900h, 6300h, 6d00h, 4000h, 4000h, 5900h, 5900h ;F6
- word 4100h, 5a00h, 6400h, 6e00h, 4100h, 4100h, 5a00h, 5a00h ;F7
- word 4200h, 5b00h, 6500h, 6f00h, 4200h, 4200h, 5b00h, 5b00h ;F8
- word 4300h, 5c00h, 6600h, 7000h, 4300h, 4300h, 5c00h, 5c00h ;F9
- word 4400h, 5d00h, 6700h, 7100h, 4400h, 4400h, 5d00h, 5d00h ;F10
- word 4500h, 4500h, 4500h, 4500h, 4500h, 4500h, 4500h, 4500h ;num
- word 4600h, 4600h, 4600h, 4600h, 4600h, 4600h, 4600h, 4600h ;scrl
- word 4700h, 4737h, 7700h, 0000h, 4737h, 4700h, 4737h, 4700h ;home
-
- word 4800h, 4838h, 0000h, 0000h, 4838h, 4800h, 4838h, 4800h ;up
- word 4900h, 4939h, 8400h, 0000h, 4939h, 4900h, 4939h, 4900h ;pgup
- word 4a2dh, 4a2dh, 0000h, 0000h, 4a2dh, 4a2dh, 4a2dh, 4a2dh ;-
- word 4b00h, 4b34h, 7300h, 0000h, 4b34h, 4b00h, 4b34h, 4b00h ;left
- word 4c00h, 4c35h, 0000h, 0000h, 4c35h, 4c00h, 4c35h, 4c00h ;Cen
- word 4d00h, 4d36h, 7400h, 0000h, 4d36h, 4d00h, 4d36h, 4d00h ;right
- word 4e2bh, 4e2bh, 0000h, 0000h, 4e2bh, 4e2bh, 4e2bh, 4e2bh ;+
- word 4f00h, 4f31h, 7500h, 0000h, 4f31h, 4f00h, 4f31h, 4f00h ;end
-
- ; norm shft ctrl alt num caps shcap shnum
- word 5000h, 5032h, 0000h, 0000h, 5032h, 5000h, 5032h, 5000h ;down
- word 5100h, 5133h, 7600h, 0000h, 5133h, 5100h, 5133h, 5100h ;pgdn
- word 5200h, 5230h, 0000h, 0000h, 5230h, 5200h, 5230h, 5200h ;ins
- word 5300h, 532eh, 0000h, 0000h, 532eh, 5300h, 532eh, 5300h ;del
- word 0,0,0,0,0,0,0,0 ; --
- word 0,0,0,0,0,0,0,0 ; --
- word 0,0,0,0,0,0,0,0 ; --
- word 5700h, 0000h, 0000h, 0000h, 5700h, 5700h, 0000h, 0000h ;F11
-
- word 5800h, 0000h, 0000h, 0000h, 5800h, 5800h, 0000h, 0000h ;F12
-
-
-
- ;****************************************************************************
- ;
- ; AL contains keyboard scan code.
-
- PutInBuffer proc near
- push ds
- push bx
-
- mov bx, 40h ;Point ES at the BIOS
- mov ds, bx ; variables.
-
- ; If the current scan code is E0 or E1, we need to take note of this fact
- ; so that we can properly process cursor keys.
-
- cmp al, 0e0h
- jne TryE1
- or KbdFlags3, 10b ;Set E0 flag
- and KbdFlags3, 0FEh ;Clear E1 flag
- jmp Done
-
- TryE1: cmp al, 0e1h
- jne DoScan
- or KbdFlags3, 1 ;Set E1 flag
- and KbdFlags3, 0FDh ;Clear E0 Flag
- jmp Done
-
-
- ; Before doing anything else, see if this is Ctrl-Alt-Del:
-
- DoScan: cmp al, DelScanCode ;5300h
- jnz TryIns
- mov bl, KbdFlags
- and bl, AltBit or CtrlBit ;Alt = bit 3, ctrl = bit 2
- cmp bl, AltBit or CtrlBit
- jne DoPIB
- mov word ptr ds:[72h], 1234h ;Warm boot flag.
- jmp dword ptr cs:RebootAdrs ;REBOOT Computer
-
- RebootAdrs dd 0ffff0000h ;Reset address.
-
-
- ; Check for the INS key here. This one needs to toggle the ins bit
- ; in the keyboard flags variables.
-
- TryIns: cmp al, InsScanCode
- jne TryInsUp
- or KbdFlags2, InsBit ;Note INS is down.
- jmp doPIB ;Pass on INS key.
-
- TryInsUp: cmp al, InsScanCode+80h ;INS up scan code.
- jne TryLShiftDn
- and KbdFlags2, not InsBit ;Note INS is up.
- xor KbdFlags, InsBit ;Toggle INS bit.
- jmp QuitPIB
-
- ; Handle the left and right shift keys down here.
-
- TryLShiftDn: cmp al, LShiftScan
- jne TryLShiftUp
- or KbdFlags, LShfBit ;Note that the left
- jmp QuitPIB ; shift key is down.
-
- TryLShiftUp: cmp al, LShiftScan+80h
- jne TryRShiftDn
- and KbdFlags, not LShfBit ;Note that the left
- jmp QuitPIB ; shift key is up.
-
-
- TryRShiftDn: cmp al, RShiftScan
- jne TryRShiftUp
- or KbdFlags, RShfBit ;Right shf is down.
- jmp QuitPIB
-
- TryRShiftUp: cmp al, RShiftScan+80h
- jne TryAltDn
- and KbdFlags, not RShfBit ;Right shf is up.
- jmp QuitPIB
-
- ; Handle the ALT key down here.
-
- TryAltDn: cmp al, AltScan
- jne TryAltUp
- or KbdFlags, AltBit ;Alt key is down.
- GotoQPIB: jmp QuitPIB
-
- TryAltUp: cmp al, AltScan+80h
- jne TryCtrlDn
- and KbdFlags, not AltBit ;Alt key is up.
- jmp DoPIB
-
-
- ; Deal with the control key down here.
-
- TryCtrlDn: cmp al, CtrlScan
- jne TryCtrlUp
- or KbdFlags, CtrlBit ;Ctrl key is down.
- jmp QuitPIB
-
- TryCtrlUp: cmp al, CtrlScan+80h
- jne TryCapsDn
- and KbdFlags, not CtrlBit ;Ctrl key is up.
- jmp QuitPIB
-
- ; Deal with the CapsLock key down here.
-
- TryCapsDn: cmp al, CapsLockScan
- jne TryCapsUp
- or KbdFlags2, CLBit ;Capslock is down.
- xor KbdFlags, CLBit ;Toggle capslock mode.
- jmp QuitPIB
-
- TryCapsUp: cmp al, CapsLockScan+80h
- jne TrySLDn
- and KbdFlags2, not CLBit ;Capslock is up.
- call SetLEDs
- jmp QuitPIB
-
- ; Deal with the Scroll Lock key down here.
-
- TrySLDn: cmp al, ScrlLockScan
- jne TrySLUp
- or KbdFlags2, SLBit ;Scrl lock is down.
- xor KbdFlags, SLBit ;Toggle scrl lock.
- jmp QuitPIB
-
- TrySLUp: cmp al, ScrlLockScan+80h
- jne TryNLDn
- and KbdFlags2, not SLBit ;Scrl lock is up.
- call SetLEDs
- jmp QuitPIB
-
- ; Handle the NumLock key down here.
-
-
- TryNLDn: cmp al, NumLockScan
- jne TryNLUp
- or KbdFlags2, NLBit ;Numlock is down.
- xor KbdFlags, NLBit ;Toggle numlock.
- jmp QuitPIB
-
- TryNLUp: cmp al, NumLockScan+80h
- jne DoPIB
- and KbdFlags2, not NLBit ;Numlock is up.
- call SetLEDs
- jmp QuitPIB
-
-
-
- ; Handle all the other keys here:
-
- DoPIB: test al, 80h ;Ignore all other up keys.
- jnz QuitPIB
-
- ; If the H.O. bit is set at this point, we'd best only have a zero in AL.
- ; Otherwise, this is an up code which we can safely ignore.
-
- call Convert
- test ax, ax ;Check for illegal code.
- je QuitPIB
-
- PutCharInBuf: push cx
- mov cx, ax
- mov ah, 5 ;Store scan code into
- int 16h ; type ahead buffer.
- pop cx
-
- QuitPIB: and KbdFlags3, 0FCh ;E0, E1 not last code.
-
- Done: pop bx
- pop ds
- ret
- PutInBuffer endp
-
-
-
-
- ;****************************************************************************
- ;
- ; Convert- AL contains a PC Scan code. Convert it to an ASCII char/Scan
- ; code pair and return the result in AX. This code assumes
- ; that DS points at the BIOS variable space (40h).
-
- Convert proc near
- push bx
-
- test al, 80h ;See if up code
- jz DownScanCode
- mov ah, al
- mov al, 0
- jmp CSDone
-
- ; Okay, we've got a down key. But before going on, let's see if we've
- ; got an ALT-Keypad sequence.
-
- DownScanCode: mov bh, 0
- mov bl, al
- shl bx, 1 ;Multiply by eight to compute
- shl bx, 1 ; row index index the scan
- shl bx, 1 ; code xlat table
-
- ; Compute modifier index as follows:
- ;
- ; if alt then modifier = 3
-
- test KbdFlags, AltBit
- je NotAlt
- add bl, 3
- jmp DoConvert
-
- ; if ctrl, then modifier = 2
-
- NotAlt: test KbdFlags, CtrlBit
- je NotCtrl
- add bl, 2
- jmp DoConvert
-
- ; Regardless of the shift setting, we've got to deal with numlock
- ; and capslock. Numlock is only a concern if the scan code is greater
- ; than or equal to 47h. Capslock is only a concern if the scan code
- ; is less than this.
-
- NotCtrl: cmp al, 47h
- jb DoCapsLk
- test KbdFlags, NLBit ;Test Numlock bit
- je NoNumLck
- test KbdFlags, LShfBit or RShfBit ;Check l/r shift.
- je NumOnly
- add bl, 7 ;Numlock and shift.
- jmp DoConvert
-
- NumOnly: add bl, 4 ;Numlock only.
- jmp DoConvert
-
- ; If numlock is not active, see if a shift key is:
-
- NoNumLck: test KbdFlags, LShfBit or RShfBit ;Check l/r shift.
- je DoConvert ;normal if no shift.
- add bl, 1
- jmp DoConvert
-
- ; If the scan code's value is below 47h, we need to check for capslock.
-
- DoCapsLk: test KbdFlags, CLBit ;Chk capslock bit
- je DoShift
- test KbdFlags, LShfBit or RShfBit ;Chk for l/r shift
- je CapsOnly
- add bl, 6 ;Shift and capslock.
- jmp DoConvert
-
- CapsOnly: add bl, 5 ;Capslock
- jmp DoConvert
-
- ; Well, nothing else is active, check for just a shift key.
-
- DoShift: test KbdFlags, LShfBit or RShfBit ;l/r shift.
- je DoConvert
- add bl, 1 ;Shift
-
- DoConvert: shl bx, 1 ;Word array
- mov ax, ScanXlat[bx]
- CSDone: pop bx
- ret
- Convert endp
-
-
-
-
- ; SetCmd- Sends the command byte in the AL register to the 8042
- ; keyboard microcontroller chip (command register at
- ; port 64h).
-
- SetCmd proc near
- push cx
- push ax ;Save command value.
- cli ;Critical region, no ints now.
-
- ; Wait until the 8042 is done processing the current command.
-
- xor cx, cx ;Allow 65,536 times thru loop.
- Wait4Empty: in al, 64h ;Read keyboard status register.
- test al, 10b ;Input buffer full?
- loopnz Wait4Empty ;If so, wait until empty.
-
- ; Okay, send the command to the 8042:
-
- pop ax ;Retrieve command.
- out 64h, al
- sti ;Okay, ints can happen again.
- pop cx
- ret
- SetCmd endp
-
-
-
- ; SendCmd- The following routine sends a command or data byte to the
- ; keyboard data port (port 60h).
-
- SendCmd proc near
- push ds
- push bx
- push cx
- mov cx, 40h
- mov ds, cx
- mov bx, ax ;Save data byte
-
- mov bh, 3 ;Retry cnt.
- RetryLp: cli ;Disable ints while accessing HW.
-
- ; Clear the Error, Acknowledge received, and resend received flags
- ; in KbdFlags4
-
- and byte ptr KbdFlags4, 4fh
-
- ; Wait until the 8042 is done processing the current command.
-
- xor cx, cx ;Allow 65,536 times thru loop.
- Wait4Empty: in al, 64h ;Read keyboard status register.
- test al, 10b ;Input buffer full?
- loopnz Wait4Empty ;If so, wait until empty.
-
- ; Okay, send the data to port 60h
-
- mov al, bl
- out 60h, al
- sti ;Allow interrupts now.
-
- ; Wait for the arrival of an acknowledgement from the keyboard ISR:
-
- xor cx, cx ;Wait a long time, if need be.
- Wait4Ack: test byp KbdFlags4, 10h ;Acknowledge received bit.
- jnz GotAck
- loop Wait4Ack
- dec bh ;Do a retry on this guy.
- jne RetryLp
-
- ; If the operation failed after 3 retries, set the error bit and quit.
-
- or byp KbdFlags4, 80h ;Set error bit.
-
- GotAck: pop cx
- pop bx
- pop ds
- ret
- SendCmd endp
-
-
-
-
- ; SetLEDs- Updates the KbdFlags4 LED bits from the KbdFlags
- ; variable and then transmits new flag settings to
- ; the keyboard.
-
- SetLEDs proc near
- push ax
- push cx
- mov al, KbdFlags
- mov cl, 4
- shr al, cl
- and al, 111b
- and KbdFlags4, 0F8h ;Clear LED bits.
- or KbdFlags4, al ;Mask in new bits.
- mov ah, al ;Save LED bits.
-
- mov al, 0ADh ;Disable kbd for now.
- call SetCmd
-
- mov al, 0EDh ;8042 set LEDs cmd.
- call SendCmd ;Send the command to 8042.
- mov al, ah ;Get parameter byte
- call SendCmd ;Send parameter to the 8042.
-
- mov al, 0AEh ;Reenable keyboard.
- call SetCmd
- mov al, 0F4h ;Restart kbd scanning.
- call SendCmd
- pop cx
- pop ax
- ret
- SetLEDs endp
-
-
- ; MyInt9- Interrupt service routine for the keyboard hardware
- ; interrupt.
-
- MyInt9 proc far
- push ds
- push ax
- push cx
-
- mov ax, 40h
- mov ds, ax
-
- mov al, 0ADh ;Disable keyboard
- call SetCmd
- cli ;Disable interrupts.
- xor cx, cx
- Wait4Data: in al, 64h ;Read kbd status port.
- test al, 10b ;Data in buffer?
- loopz Wait4Data ;Wait until data available.
- in al, 60h ;Get keyboard data.
- cmp al, 0EEh ;Echo response?
- je QuitInt9
- cmp al, 0FAh ;Acknowledge?
- jne NotAck
- or KbdFlags4, 10h ;Set ack bit.
- jmp QuitInt9
-
- NotAck: cmp al, 0FEh ;Resend command?
- jne NotResend
- or KbdFlags4, 20h ;Set resend bit.
- jmp QuitInt9
-
- ; Note: other keyboard controller commands all have their H.O. bit set
- ; and the PutInBuffer routine will ignore them.
-
- NotResend: call PutInBuffer ;Put in type ahead buffer.
-
- QuitInt9: mov al, 0AEh ;Reenable the keyboard
- call SetCmd
-
- mov al, 20h ;Send EOI (end of interrupt)
- out 20h, al ; to the 8259A PIC.
- pop cx
- pop ax
- pop ds
- iret
- MyInt9 endp
-
-
-
- Main proc
- assume ds:cseg
-
- mov ax, cseg
- mov ds, ax
-
- print
- byte "INT 9 Replacement",cr,lf
- byte "Installing....",cr,lf,0
-
- ; Patch into the INT 9 interrupt vector. Note that the
- ; statements above have made cseg the current data segment,
- ; so we can store the old INT 9 value directly into
- ; the OldInt9 variable.
-
- cli ;Turn off interrupts!
- mov ax, 0
- mov es, ax
- mov ax, es:[9*4]
- mov word ptr OldInt9, ax
- mov ax, es:[9*4 + 2]
- mov word ptr OldInt9+2, ax
- mov es:[9*4], offset MyInt9
- mov es:[9*4+2], cs
- sti ;Okay, ints back on.
-
-
- ; We're hooked up, the only thing that remains is to terminate and
- ; stay resident.
-
- print
- byte "Installed.",cr,lf,0
-
- mov ah, 62h ;Get this program's PSP
- int 21h ; value.
-
- mov dx, EndResident ;Compute size of program.
- sub dx, bx
- mov ax, 3100h ;DOS TSR command.
- int 21h
- Main endp
- cseg ends
-
- sseg segment para stack 'stack'
- stk db 1024 dup ("stack ")
- sseg ends
-
- zzzzzzseg segment para public 'zzzzzz'
- LastBytes db 16 dup (?)
- zzzzzzseg ends
- end Main
-
-
-
-